import {
  FormOutlined,
  MinusCircleOutlined,
  PlusCircleOutlined,
} from "@ant-design/icons";
import {
  Alert,
  Button,
  Col,
  Divider,
  Drawer,
  Image,
  Input,
  Progress,
  Row,
  Space,
} from "antd";
import Paragraph from "antd/lib/typography/Paragraph";
import Text from "antd/lib/typography/Text";
import Title from "antd/lib/typography/Title";
import { Feature, MapBrowserEvent } from "ol";
import { Coordinate } from "ol/coordinate";
import { singleClick } from "ol/events/condition";
import Geometry from "ol/geom/Geometry";
import LineString from "ol/geom/LineString";
import Point from "ol/geom/Point";
import Select from "ol/interaction/Select";
import React from "react";
import { makeHighlight } from "./geom/highlightlib";
import { getMainMap } from "./geom/MainMap";

let enableSelecting: boolean = true;

const select = new Select({
  style: null,
  condition: function (e: MapBrowserEvent<any>): boolean {
    if (singleClick(e)) {
      const features = getMainMap().getFeaturesAtPixel(e.pixel);
      if (features.length === 1) {
        const featureType = features[0].getGeometry()?.getType();
        return (
          enableSelecting &&
          (featureType === "Point" || featureType === "LineString")
        );
      }
    }
    return false;
  },
});

export function selectFeature(feature: Feature<any> | undefined = undefined) {
  const selected = select.getFeatures();
  selected.clear();
  if (feature !== undefined) {
    selected.push(feature);
  }
}

export function beginSelecting() {
  enableSelecting = true;
}

export function endSelecting() {
  enableSelecting = false;
}

type Props = {
  add: (feature: Feature<Geometry>) => undefined;
  del: (index: number) => undefined;
  find: (feature: Feature<Geometry>) => number | undefined;
  update: () => void;
  routing: boolean;
};

type State = {
  feature: Feature<Geometry> | null;
  subDraw: boolean;
};

type SubDrawerProps = {
  text: string;
  onOK: (text: string) => void;
  onCancel: () => void;
  visible: boolean;
};

class SubDrawer extends React.Component<SubDrawerProps, { text?: string }> {
  constructor(props: SubDrawerProps) {
    super(props);
    this.state = { text: undefined };
  }

  handleChanging: React.ChangeEventHandler<HTMLTextAreaElement> = (e) => {
    this.setState({ text: e.target.value });
  };

  handleOK: React.MouseEventHandler<HTMLElement> = () => {
    this.setState({ text: undefined });
    this.props.onOK(this.state.text ?? "");
  };

  handleCancel = () => {
    this.setState({ text: undefined });
    this.props.onCancel();
  };

  render(): React.ReactNode {
    const value = this.state.text ?? this.props.text;
    return (
      <Drawer
        mask
        title="游玩计划"
        visible={this.props.visible}
        closable={false}
      >
        <Space direction="vertical">
          <Input.TextArea
            placeholder="请输入在该地点的计划"
            onChange={this.handleChanging}
            allowClear
            rows={8}
            value={value}
          />
          <Row justify="end">
            <Space>
              <Button type="primary" onClick={this.handleOK}>
                提交
              </Button>
              <Button type="default" onClick={this.handleCancel}>
                取消
              </Button>
            </Space>
          </Row>
        </Space>
      </Drawer>
    );
  }
}

export default class DetailDrawerBuilder extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { feature: null, subDraw: false };
  }

  componentDidMount = () => {
    select.getFeatures().on("add", (e) => {
      const feature: Feature<Geometry> = e.element;
      const [on, off] = makeHighlight(feature);
      on();
      select.getFeatures().on("remove", off);
      getMainMap()
        .getView()
        .animate({
          center: getCenterPoint(feature),
          zoom: feature.getGeometry()?.getType() === "Point" ? 19 : 16.5,
          duration: 500,
        });
      this.setState({ feature: feature, subDraw: false });
    });
    getMainMap().addInteraction(select);
  };

  onClose = () => {
    selectFeature();
    this.setState({ feature: null, subDraw: false });
  };

  maybeCreateButton(
    feature: Feature<Geometry>,
    index?: number
  ): React.ReactNode {
    if (!this.props.routing) {
      return <></>;
    } else {
      if (index === undefined) {
        return (
          <Row justify="end">
            <Button
              size="large"
              type="primary"
              icon={<PlusCircleOutlined />}
              onClick={() =>
                this.setState({
                  subDraw: true,
                })
              }
            >
              加入我的路径
            </Button>
          </Row>
        );
      } else {
        return (
          <Row justify="end">
            <Space>
              <Button
                size="large"
                type="primary"
                icon={<FormOutlined />}
                onClick={() => {
                  this.setState({ subDraw: true });
                }}
              >
                编辑
              </Button>
              <Button
                size="large"
                danger
                icon={<MinusCircleOutlined />}
                onClick={() => {
                  this.props.del(index);
                }}
              >
                从我的路径中删除
              </Button>
            </Space>
          </Row>
        );
      }
    }
  }

  renderPoint(feature: Feature<Point>): React.ReactNode {
    return (
      <Space direction="vertical">
        <Title level={2}>蒙太奇大漩涡</Title>
        <Paragraph style={{ textAlign: "right" }}>
          <Text type="secondary">9:00-22:00</Text>
        </Paragraph>
        <Divider orientation="left">刺激</Divider>
        <Paragraph>
          全国最大的大喇叭水上设备要数国色天香水上乐园的蒙太奇大漩涡，游客4人一组乘坐橡皮艇在密封的滑倒在将近90的角度快速滑下，紧接着巨大的重力作用，将游客们卷入巨大的大喇叭内，而正当你觉得这应该结束了吧，而这只是暴风雨来临之前的一点毛毛雨，之后的过程你所面临的不是平淡与无奇，而是持续的兴奋和刺激，还在等什么，快速尖叫起来吧！
        </Paragraph>
        <Row>
          <Col span={11}>
            <Image src="http://www.gstxdpxt.com/userlist/gstxdpxt/data/userpic/20130719212061.jpg" />
          </Col>
          <Col span={11} offset={1}>
            <Image src="http://www.gstxdpxt.com/userlist/gstxdpxt/data/userpic/20130719212653.jpg" />
          </Col>
        </Row>
        <Row>
          <Col span={11}>
            <Image src="http://www.gstxdpxt.com/userlist/gstxdpxt/data/userpic/20130719216861.jpg" />
          </Col>
          <Col span={11} offset={1}>
            <Image src="http://www.gstxdpxt.com/userlist/gstxdpxt/data/userpic/20130312214910.jpg" />
          </Col>
        </Row>
        <Row>
          <Col span={8}>
            <Row>
              <Col span={24}>
                <Progress type="circle" strokeColor="#FFFF66" percent={70} />
              </Col>
            </Row>
            <Row>
              <Col span={24} style={{ textAlign: "center" }}>
                <Text strong>惊险度</Text>
              </Col>
            </Row>
          </Col>
          <Col span={8}>
            <Row>
              <Col span={24}>
                <Progress type="circle" percent={65} strokeColor="#FF6666" />
              </Col>
            </Row>
            <Row>
              <Col span={24} style={{ textAlign: "center" }}>
                <Text strong>欢乐度</Text>
              </Col>
            </Row>
          </Col>
          <Col span={8}>
            <Row>
              <Col span={24}>
                <Progress type="circle" percent={50} strokeColor="#99CC66" />
              </Col>
            </Row>
            <Row>
              <Col span={24} style={{ textAlign: "center" }}>
                <Text strong>挑战度</Text>
              </Col>
            </Row>
          </Col>
        </Row>
        <Alert message="60/船/小时，每超时10分钟，加收10元" type="success" />
      </Space>
    );
  }

  renderFeature(feature: Feature<Geometry>): React.ReactNode {
    if (feature.getGeometry()?.getType() === "Point") {
      return this.renderPoint(feature as Feature<Point>);
    } else {
      return <Title>道路</Title>;
    }
  }

  render(): React.ReactNode {
    if (this.state.feature === null) {
      return <></>;
    } else {
      const feature: Feature<Geometry> = this.state.feature;
      const index = this.props.find(feature);
      const initText = index === null ? "" : feature.get("routing-remark");
      return (
        <Drawer
          visible={true}
          onClose={this.onClose}
          placement="right"
          mask={false}
          width="35%"
        >
          <Space direction="vertical">
            {this.renderFeature(feature)}
            {this.maybeCreateButton(feature, index)}
          </Space>
          <SubDrawer
            text={initText}
            visible={this.state.subDraw}
            onOK={(text) => {
              feature.set("routing-remark", text);
              if (index === undefined) {
                this.props.add(feature);
              } else {
                this.props.update();
              }
              this.setState({ subDraw: false });
            }}
            onCancel={() => {
              this.setState({ subDraw: false });
            }}
          />
        </Drawer>
      );
    }
  }
}

export function getCenterPoint(feature: Feature<Geometry>): Coordinate {
  switch (feature.getGeometry()?.getType()) {
    case "Point":
      const point = feature.getGeometry() as Point;
      return point.getCoordinates();
    case "LineString":
      const line = feature.getGeometry() as LineString;
      const [fst, lst] = [line.getFirstCoordinate(), line.getLastCoordinate()];
      return [(fst[0] + lst[0]) / 2, (fst[1] + lst[1]) / 2];
    default:
      console.error("Unable to process feature %s", feature);
      return [];
  }
}
